package com.tec.security.utils.security.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tec.security.utils.security.entity.UserInformation;
import com.tec.security.utils.security.mapper.UserInformationMapper;
import com.tec.security.utils.security.mapper.UserKeyMapper;
import com.tec.security.utils.security.mapper.UserRoleMapper;
import com.tec.security.utils.security.entity.UserInfo;
import com.tec.security.utils.security.entity.UserKey;
import com.tec.security.utils.security.entity.UserRole;
import com.tec.security.utils.security.service.UserKeyService;
import com.tec.security.utils.captcha.CaptchaRedisService;
import com.tec.security.utils.response.Result;
import com.tec.security.utils.security.service.UserlogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author 陆林
 * @description 针对表【user_key】的数据库操作Service实现
 * @date 2023-11-21 21:56:03
 */
@Service
public class UserKeyServiceImpl extends ServiceImpl<UserKeyMapper, UserKey> implements UserKeyService {
    @Value("${passwordKey.publicKey}")
    private String publicKey;
    @Value("${passwordKey.privateKey}")
    private String privateKey;
    private final UserKeyMapper userKeyMapper;
    private final UserInformationMapper userInformationMapper;
    private final UserRoleMapper userRoleMapper;
    private final CaptchaRedisService captchaRedisService;
    private final UserlogService userlogService;

    @Autowired
    public UserKeyServiceImpl(UserKeyMapper userKeyMapper, UserInformationMapper userInformationMapper, UserRoleMapper userRoleMapper, CaptchaRedisService captchaRedisService, UserlogService userlogService) {
        this.userKeyMapper = userKeyMapper;
        this.userInformationMapper = userInformationMapper;
        this.userRoleMapper = userRoleMapper;
        this.captchaRedisService = captchaRedisService;
        this.userlogService = userlogService;
    }

    /**
     * @description 登录
     * @author 陆林
     * @date 2023-11-21
     */
    @Override
    public Result login(String username, String password, boolean rememberMe) {
        boolean addKey;
        QueryWrapper<UserKey> userKeyQueryWrapper = new QueryWrapper<>();
        userKeyQueryWrapper.eq("username", username);
        UserKey user = userKeyMapper.selectOne(userKeyQueryWrapper);
        if (user != null) {
            try {
                user.setPassword(SaSecureUtil.rsaDecryptByPrivate(privateKey, user.getPassword()));
                addKey = true;
            } catch (Exception ioException) {
                addKey = false;
            }
            if (Objects.equals(user.getPassword(), password)) {
                if (!addKey) {
                    password = SaSecureUtil.rsaEncryptByPublic(publicKey, password);
                    UpdateWrapper<UserKey> userKeyUpdateWrapper = new UpdateWrapper<>();
                    userKeyUpdateWrapper.eq("username", username).set("password", password);
                    userKeyMapper.update(null, userKeyUpdateWrapper);
                }
                StpUtil.login(user.getUuid(), new SaLoginModel()
                        .setIsLastingCookie(rememberMe)
                        .setIsWriteHeader(false));
                return Result.success("登录成功", null);
            } else {
                return Result.refuse("密码错误", null);
            }
        } else {
            return Result.failure("账号未找到", null);
        }
    }

    /**
     * @description 修改密码
     * @author 陆林
     * @date 2023-11-21
     */
    @Override
    public Result doUpdatePassword(String uuid, String password, String password_update) {
        QueryWrapper<UserKey> userKeyQueryWrapper = new QueryWrapper<>();
        userKeyQueryWrapper.eq("uuid", uuid);
        UserKey user = userKeyMapper.selectOne(userKeyQueryWrapper);
        user.setPassword(SaSecureUtil.rsaDecryptByPrivate(privateKey, user.getPassword()));
        if (Objects.equals(user.getPassword(), password)) {
            password_update = SaSecureUtil.rsaEncryptByPublic(publicKey, password_update);
            UpdateWrapper<UserKey> userKeyUpdateWrapper = new UpdateWrapper<>();
            userKeyUpdateWrapper.eq("uuid", uuid).set("password", password_update);
            userKeyMapper.update(null, userKeyUpdateWrapper);
            userlogService.userInfo(uuid,"修改密码","04");
            return Result.success("密码更新成功", null);
        } else {
            return Result.refuse("密码错误", null);
        }
    }

    /**
     * @description 登录状态
     * @author 陆林
     * @date 2023-11-21
     */
    @Override
    public Result isLogin() {
        if (StpUtil.isLogin()) {
            return Result.success("已登录",null);
        } else {
            return Result.diy(403,"未登录", null);
        }
    }

    /**
     * @description 找回密码（邮箱）
     * @author 陆林
     * @date 2023-11-21
     */
    @Override
    public Result doPasswordReset(String password, String email, String code) {
        String key = captchaRedisService.getCaptcha(email);
        if (key.equalsIgnoreCase(code)) {
            QueryWrapper<UserKey> userKeyQueryWrapper = new QueryWrapper<>();
            userKeyQueryWrapper.eq("email", email);
            UserKey user = userKeyMapper.selectOne(userKeyQueryWrapper);
            if (user != null) {
                UpdateWrapper<UserKey> userKeyUpdateWrapper = new UpdateWrapper<>();
                password = SaSecureUtil.rsaEncryptByPublic(publicKey, password);
                userKeyUpdateWrapper.eq("email", email).set("password", password);
                if(userKeyMapper.update(null, userKeyUpdateWrapper) > 0){
                    captchaRedisService.deleted(email);
                    userlogService.userInfo(user.getUuid(),"找回密码","05");
                   return Result.success("密码重设成功", null);
                }else{
                    return Result.failure("密码重设失败", null);
                }
            } else {
                return Result.failure("邮箱不存在", null);
            }
        } else {
            return Result.failure("验证码错误", null);
        }
    }

    /**
     * @description 退出登录
     * @author 陆林
     * @date 2023-11-21
     */
    @Override
    public Result doLogout(String token) {
        StpUtil.logout();
        return Result.success("退出登录成功", null);
    }

    /**
     * @description 账号注册
     * @author 陆林
     * @date 2023-11-22
     */
    @Override
    public Result signup(UserInfo user) {
        String key = captchaRedisService.getCaptcha(user.getEmail());
        if (user.getCode().equalsIgnoreCase(key)) {
            QueryWrapper<UserKey> userKeyQueryWrapper_u = new QueryWrapper<>();
            userKeyQueryWrapper_u.eq("username", user.getUsername());
            UserKey user_u = userKeyMapper.selectOne(userKeyQueryWrapper_u);
            if (user_u == null) {
                QueryWrapper<UserKey> userKeyQueryWrapper_e = new QueryWrapper<>();
                userKeyQueryWrapper_e.eq("email", user.getEmail());
                UserKey user_e = userKeyMapper.selectOne(userKeyQueryWrapper_e);
                if (user_e == null) {
                    SimpleDateFormat formatterDate = new SimpleDateFormat("yyyy-MM-dd");
                    String date=formatterDate.format(System.currentTimeMillis());
                    String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
                    UserKey userKey = new UserKey();
                    userKey.setPassword(SaSecureUtil.rsaEncryptByPublic(publicKey, user.getPassword()));
                    userKey.setUsername(user.getUsername());
                    userKey.setEmail(user.getEmail());
                    userKey.setUuid(uuid);
                    userKey.setEnabled(true);
                    UserInformation userInformation = new UserInformation();
                    userInformation.setUuid(uuid);
                    userInformation.setGrade(user.getGrade());
                    userInformation.setUrl(user.getUrl());
                    userInformation.setProfession(user.getProfession());
                    userInformation.setName(user.getName());
                    userInformation.setEmail(user.getEmail());
                    userInformation.setSex(user.getSex());
                    userInformation.setIdentity(user.getIdentity());
                    userInformation.setDepartment(user.getDepartment());
                    userInformation.setSignuptime(date);
                    UserRole userRole = new UserRole();
                    userRole.setUuid(uuid);
                    userRole.setRole(3);
                    userKeyMapper.insert(userKey);
                    userInformationMapper.insert(userInformation);
                    userRoleMapper.insert(userRole);
                    Map<String, Object> result = new HashMap<>();
                    result.put("username", user.getUsername());
                    result.put("email", user.getEmail());
                    StpUtil.login(uuid);
                    userlogService.userInfo(uuid,"账号注册","06");
                    return Result.success("注册成功", result);
                } else {
                    return Result.failure("邮箱已被占用", null);
                }
            } else {
                return Result.failure("用户已存在", null);
            }
        } else {
            return Result.failure("验证码错误", null);
        }
    }

    @Override
    public Result getUserInfo() {
        QueryWrapper<UserInformation> userInformationQueryWrapper=new QueryWrapper<>();
        userInformationQueryWrapper.eq("uuid",StpUtil.getLoginId());
        UserInformation userInformation=userInformationMapper.selectOne(userInformationQueryWrapper);
        userInformation.setUuid(null);
        userInformation.setId(null);
        return Result.success("请求成功",userInformation);
    }
}